import type { RunTimeLayoutConfig, RequestConfig, AxiosResponse } from 'umi';
import { history, } from 'umi';

import JSEncrypt from 'jsencrypt';

import { CommonApi, UserApi } from '@/services/admin';
import * as Storage from '@/services/storage';
import { encrypt, decrypt } from '@/services/security';

const loginPath = '/user/login';
let jsEncrypt: JSEncrypt;

// 运行时配置
function setHeaders(secretKey: string, secretIv: string, token: string | null): any {
  let headers = {
    'Content-Type': 'application/json;charset=utf-8',
    CRYPTO: secretKey,
    IV: secretIv,
    token: '',
  };
  if (token) {
    headers = { ...headers, token: Storage.TOKEN_PREFIX + token };
  }
  return headers;
}

export const request: RequestConfig = {
  timeout: 3000,
  requestInterceptors: [
    (url, options)=>{
      if (url === '/icloud/common/public-key') {
        const headers = { 'Content-Type': 'application/json;charset=utf-8' };
        return {
          url,
          options: { ...options, interceptors: true, headers },
        };
      }
      const crypto = Storage.getItem(Storage.KEY_CRYPTO);
      const iv = Storage.getItem(Storage.KEY_IV);
      const token = Storage.getItem(Storage.KEY_TOKEN);
      const secretKey = jsEncrypt.encrypt(crypto) as string;
      const secretIv = jsEncrypt.encrypt(iv) as string;
      const headers = setHeaders(secretKey, secretIv, token);
      const method = options.method
      let ret = {
        url: `${url}`, 
        options:{...options, interceptors: true, headers} 
      }
      if (method==='post'){
        const data = options.data?encrypt(crypto, iv, JSON.stringify(options.data)):'';
        ret.options.data = data;
      }else if (method==='get'){
        const params = options.params?encrypt(crypto, iv, JSON.stringify(options.params)):'';
        ret.options.params = params;
      }
      return ret;
    }
  ],
  responseInterceptors: [
    (resp: AxiosResponse)=>{
      const { config, data } = resp;
      if (config.url!.indexOf('/icloud/common/public-key') !== -1) {
        return resp;
      }
      const crypto = Storage.getItem(Storage.KEY_CRYPTO);
      const iv = Storage.getItem(Storage.KEY_IV);
      const innerData = decrypt(crypto, iv, data.data);
      resp.data = {...data, data:innerData}
      console.log('resp:', resp);
      return resp;
    }
  ],
};

// 全局初始化数据配置，用于 Layout 用户信息和权限初始化
// 更多信息见文档：https://next.umijs.org/docs/api/runtime-config#getinitialstate
export async function getInitialState(): Promise<{ name: string }> {
  const fetchPublicKey = async () => {
    try {
      const msg = await CommonApi.publicKey();
      return msg.data;
    } catch (error) {
      history.push(loginPath);
    }
    return '';
  };

    // --- begin ---
    let publicKey: string = await fetchPublicKey();
    Storage.setItem(Storage.KEY_PUBLIC, publicKey);
    Storage.setItem(Storage.KEY_CRYPTO, '0987654321654321');
    Storage.setItem(Storage.KEY_IV, '1234567890123456');

    if (jsEncrypt === null || jsEncrypt === undefined) {
      jsEncrypt = new JSEncrypt();
    }
    jsEncrypt.setPublicKey(publicKey);
    // --- end ---
  return { name: 'i-cloud' };
}

export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
  return {
    logo: 'https://img.alicdn.com/tfs/TB1YHEpwUT1gK0jSZFhXXaAtVXa-28-27.svg',
    menu: {
      locale: false,
    },
    layout: 'mix',
    logout: ()=> {
      UserApi.logout().finally(()=>{
        history.replace('/')
      })
    },
    onPageChange: () => {
      const { location } = history;
      // 如果没有登录，重定向到 login
      const token = Storage.getItem(Storage.KEY_TOKEN)
      if (Storage.isEmpty(token) && location.pathname !== loginPath) {
        history.push(loginPath);
      }
    },
  };
};


